package com.breeze.components.task.lock;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import jakarta.annotation.Resource;
import java.lang.reflect.Method;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

/**
 * 定时任务锁注解切面
 *
 * @author breeze
 */
@Aspect
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE + 1)
public class LockScheduledAspect {

  @Resource private DistributedLockService distributedLockService;

  @Around("@annotation(lockScheduled)")
  public Object around(ProceedingJoinPoint joinPoint, LockScheduled lockScheduled) {
    // 锁key
    String lockKey = lockScheduled.value();
    Assert.notNull(lockKey, "lock key must be configured");

    // 执行方法全类名
    Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
    String methodName =
        StrUtil.format("{}.{}", method.getDeclaringClass().getName(), method.getName());

    // 调度类型 调度配置
    ScheduleType scheduleType = ScheduleType.scheduleType(lockScheduled);
    String scheduleConf = scheduleType.scheduleConf(lockScheduled);
    return distributedLockService.tryLockRet(
        lockKey,
        methodName,
        scheduleType,
        scheduleConf,
        () -> {
          try {
            return joinPoint.proceed();
          } catch (Throwable e) {
            log.error("LockScheduled执行异常,methodName:{}", methodName, e);
          }
          return null;
        });
  }
}
